/*
 * UART_K230.c - UART K230通信驱动实现文件
 * 适用于MSPM0G3507微控制器
 * 专门用于与K230开发板进行串口通信
 */

#include "UART_K230.h"
#include "Driver/CLOCK/clock.h"
#include <string.h>
#include <stdio.h>
#include <stdarg.h>

// 全局默认UART_K230句柄
UART_K230_Handle_t g_defaultK230;

// 私有函数声明
static void UART_K230_BufferInit(UART_K230_TxBuffer_t *txBuf, UART_K230_RxBuffer_t *rxBuf, UART_K230_LineBuffer_t *lineBuf);
static bool UART_K230_TxBufferPut(UART_K230_TxBuffer_t *buffer, uint8_t data);
static bool UART_K230_TxBufferGet(UART_K230_TxBuffer_t *buffer, uint8_t *data);
static bool UART_K230_RxBufferPut(UART_K230_RxBuffer_t *buffer, uint8_t data);
static bool UART_K230_RxBufferGet(UART_K230_RxBuffer_t *buffer, uint8_t *data);
static uint16_t UART_K230_TxBufferFreeSpace(const UART_K230_TxBuffer_t *buffer);
static uint16_t UART_K230_RxBufferDataCount(const UART_K230_RxBuffer_t *buffer);
static void UART_K230_EnableInterrupts(UART_K230_Handle_t *handle, bool txEnable, bool rxEnable);
static uint32_t UART_K230_GetTick(void);
static bool UART_K230_IsTimeout(uint32_t startTime, uint32_t timeout);
static void UART_K230_ProcessLineBuffer(UART_K230_Handle_t *handle, uint8_t data);

/**
 * @brief 初始化UART_K230驱动
 */
UART_K230_Status_t UART_K230_Init(UART_K230_Handle_t *handle, const UART_K230_Config_t *config)
{
    if (handle == NULL || config == NULL) {
        return UART_K230_STATUS_ERROR;
    }

    // 设置UART实例为UART_K230（UART3）
    handle->instance = UART_K230_INST;
    
    // 初始化缓冲区
    UART_K230_BufferInit(&handle->txBuffer, &handle->rxBuffer, &handle->lineBuffer);
    
    // 清除忙标志
    handle->txBusy = false;
    handle->rxBusy = false;
    handle->lineMode = config->enableLineMode;
    handle->lastActivity = UART_K230_GetTick();
    
    // 清除回调函数
    handle->dataCallback = NULL;
    handle->lineCallback = NULL;
    
    // 设置行结束符
    handle->lineBuffer.terminator = config->lineTerminator;
    
    // 启用中断
    UART_K230_EnableInterrupts(handle, config->enableTxInterrupt, config->enableRxInterrupt);
    
    return UART_K230_STATUS_SUCCESS;
}

/**
 * @brief 反初始化UART_K230驱动
 */
UART_K230_Status_t UART_K230_DeInit(UART_K230_Handle_t *handle)
{
    if (handle == NULL) {
        return UART_K230_STATUS_ERROR;
    }

    // 禁用中断
    UART_K230_EnableInterrupts(handle, false, false);
    
    // 清空缓冲区
    UART_K230_FlushTxBuffer(handle);
    UART_K230_FlushRxBuffer(handle);
    UART_K230_FlushLineBuffer(handle);
    
    // 重置状态
    handle->txBusy = false;
    handle->rxBusy = false;
    handle->lineMode = false;
    handle->dataCallback = NULL;
    handle->lineCallback = NULL;
    
    return UART_K230_STATUS_SUCCESS;
}

/**
 * @brief 发送单个字节
 */
UART_K230_Status_t UART_K230_SendByte(UART_K230_Handle_t *handle, uint8_t data)
{
    if (handle == NULL) {
        return UART_K230_STATUS_ERROR;
    }

    // 等待FIFO有空间
    while (DL_UART_Main_isTXFIFOFull(handle->instance)) {
        // 等待
    }
    
    // 直接发送数据
    DL_UART_Main_transmitData(handle->instance, data);
    handle->lastActivity = UART_K230_GetTick();
    
    return UART_K230_STATUS_SUCCESS;
}

/**
 * @brief 发送数据缓冲区
 */
UART_K230_Status_t UART_K230_SendData(UART_K230_Handle_t *handle, const uint8_t *data, uint16_t length)
{
    if (handle == NULL || data == NULL || length == 0) {
        return UART_K230_STATUS_ERROR;
    }

    for (uint16_t i = 0; i < length; i++) {
        UART_K230_Status_t status = UART_K230_SendByte(handle, data[i]);
        if (status != UART_K230_STATUS_SUCCESS) {
            return status;
        }
    }
    
    return UART_K230_STATUS_SUCCESS;
}

/**
 * @brief 发送字符串
 */
UART_K230_Status_t UART_K230_SendString(UART_K230_Handle_t *handle, const char *str)
{
    if (handle == NULL || str == NULL) {
        return UART_K230_STATUS_ERROR;
    }

    return UART_K230_SendData(handle, (const uint8_t *)str, strlen(str));
}

/**
 * @brief 发送字符串并添加换行符
 */
UART_K230_Status_t UART_K230_SendLine(UART_K230_Handle_t *handle, const char *str)
{
    if (handle == NULL) {
        return UART_K230_STATUS_ERROR;
    }

    UART_K230_Status_t status = UART_K230_STATUS_SUCCESS;
    
    if (str != NULL) {
        status = UART_K230_SendString(handle, str);
        if (status != UART_K230_STATUS_SUCCESS) {
            return status;
        }
    }
    
    // 发送换行符
    status = UART_K230_SendByte(handle, '\r');
    if (status == UART_K230_STATUS_SUCCESS) {
        status = UART_K230_SendByte(handle, '\n');
    }
    
    return status;
}

/**
 * @brief 格式化输出（类似printf）
 */
UART_K230_Status_t UART_K230_Printf(UART_K230_Handle_t *handle, const char *format, ...)
{
    if (handle == NULL || format == NULL) {
        return UART_K230_STATUS_ERROR;
    }

    char buffer[512];  // K230可能需要更大的缓冲区
    va_list args;
    
    va_start(args, format);
    int len = vsnprintf(buffer, sizeof(buffer), format, args);
    va_end(args);
    
    if (len < 0 || len >= sizeof(buffer)) {
        return UART_K230_STATUS_ERROR;
    }
    
    return UART_K230_SendData(handle, (const uint8_t *)buffer, len);
}

/**
 * @brief 接收单个字节
 */
UART_K230_Status_t UART_K230_ReceiveByte(UART_K230_Handle_t *handle, uint8_t *data)
{
    if (handle == NULL || data == NULL) {
        return UART_K230_STATUS_ERROR;
    }

    // 尝试从接收缓冲区获取数据
    if (UART_K230_RxBufferGet(&handle->rxBuffer, data)) {
        handle->lastActivity = UART_K230_GetTick();
        return UART_K230_STATUS_SUCCESS;
    }
    
    // 缓冲区为空，尝试直接从FIFO读取
    if (!DL_UART_Main_isRXFIFOEmpty(handle->instance)) {
        *data = DL_UART_Main_receiveData(handle->instance);
        handle->lastActivity = UART_K230_GetTick();
        
        // 如果启用了行模式，处理行缓冲区
        if (handle->lineMode) {
            UART_K230_ProcessLineBuffer(handle, *data);
        }
        
        return UART_K230_STATUS_SUCCESS;
    }
    
    return UART_K230_STATUS_BUFFER_EMPTY;
}

/**
 * @brief 接收数据到缓冲区
 */
UART_K230_Status_t UART_K230_ReceiveData(UART_K230_Handle_t *handle, uint8_t *data, uint16_t length, uint16_t *receivedLength, uint32_t timeout)
{
    if (handle == NULL || data == NULL || receivedLength == NULL) {
        return UART_K230_STATUS_ERROR;
    }

    *receivedLength = 0;
    uint32_t startTime = UART_K230_GetTick();
    
    for (uint16_t i = 0; i < length; i++) {
        // 检查超时
        if (UART_K230_IsTimeout(startTime, timeout)) {
            return (*receivedLength > 0) ? UART_K230_STATUS_SUCCESS : UART_K230_STATUS_TIMEOUT;
        }
        
        UART_K230_Status_t status = UART_K230_ReceiveByte(handle, &data[i]);
        if (status == UART_K230_STATUS_SUCCESS) {
            (*receivedLength)++;
        } else if (status != UART_K230_STATUS_BUFFER_EMPTY) {
            break;
        }
        // 如果缓冲区为空，继续等待
    }
    
    return (*receivedLength > 0) ? UART_K230_STATUS_SUCCESS : UART_K230_STATUS_BUFFER_EMPTY;
}

/**
 * @brief 接收一行数据（以换行符结束）
 */
UART_K230_Status_t UART_K230_ReceiveLine(UART_K230_Handle_t *handle, char *line, uint16_t maxLength, uint32_t timeout)
{
    if (handle == NULL || line == NULL || maxLength == 0) {
        return UART_K230_STATUS_ERROR;
    }

    uint32_t startTime = UART_K230_GetTick();
    
    // 如果已经有完整行，直接返回
    if (handle->lineBuffer.ready) {
        uint16_t copyLen = (handle->lineBuffer.length < maxLength - 1) ? handle->lineBuffer.length : maxLength - 1;
        strncpy(line, handle->lineBuffer.buffer, copyLen);
        line[copyLen] = '\0';
        
        // 清空行缓冲区
        UART_K230_FlushLineBuffer(handle);
        return UART_K230_STATUS_SUCCESS;
    }
    
    // 等待完整行数据
    while (!UART_K230_IsTimeout(startTime, timeout)) {
        uint8_t data;
        if (UART_K230_ReceiveByte(handle, &data) == UART_K230_STATUS_SUCCESS) {
            // 数据已在ReceiveByte中处理到行缓冲区
            if (handle->lineBuffer.ready) {
                uint16_t copyLen = (handle->lineBuffer.length < maxLength - 1) ? handle->lineBuffer.length : maxLength - 1;
                strncpy(line, handle->lineBuffer.buffer, copyLen);
                line[copyLen] = '\0';
                
                // 清空行缓冲区  
                UART_K230_FlushLineBuffer(handle);
                return UART_K230_STATUS_SUCCESS;
            }
        }
        
        // 短暂延时避免CPU占用过高
        for (volatile int i = 0; i < 1000; i++);
    }
    
    return UART_K230_STATUS_TIMEOUT;
}

/**
 * @brief 检查是否有完整的行数据可读
 */
bool UART_K230_IsLineReady(UART_K230_Handle_t *handle)
{
    if (handle == NULL) {
        return false;
    }
    
    return handle->lineBuffer.ready;
}

/**
 * @brief 获取接收缓冲区中的数据数量
 */
uint16_t UART_K230_GetRxDataCount(UART_K230_Handle_t *handle)
{
    if (handle == NULL) {
        return 0;
    }
    
    return UART_K230_RxBufferDataCount(&handle->rxBuffer);
}

/**
 * @brief 获取发送缓冲区中的空闲空间
 */
uint16_t UART_K230_GetTxFreeSpace(UART_K230_Handle_t *handle)
{
    if (handle == NULL) {
        return 0;
    }
    
    return UART_K230_TxBufferFreeSpace(&handle->txBuffer);
}

/**
 * @brief 清空接收缓冲区
 */
void UART_K230_FlushRxBuffer(UART_K230_Handle_t *handle)
{
    if (handle == NULL) {
        return;
    }
    
    handle->rxBuffer.head = 0;
    handle->rxBuffer.tail = 0;
    handle->rxBuffer.count = 0;
}

/**
 * @brief 清空发送缓冲区
 */
void UART_K230_FlushTxBuffer(UART_K230_Handle_t *handle)
{
    if (handle == NULL) {
        return;
    }
    
    handle->txBuffer.head = 0;
    handle->txBuffer.tail = 0;
    handle->txBuffer.count = 0;
}

/**
 * @brief 清空行缓冲区
 */
void UART_K230_FlushLineBuffer(UART_K230_Handle_t *handle)
{
    if (handle == NULL) {
        return;
    }
    
    handle->lineBuffer.length = 0;
    handle->lineBuffer.ready = false;
    memset(handle->lineBuffer.buffer, 0, sizeof(handle->lineBuffer.buffer));
}

/**
 * @brief 设置数据接收回调函数
 */
void UART_K230_SetDataCallback(UART_K230_Handle_t *handle, UART_K230_DataCallback_t callback)
{
    if (handle == NULL) {
        return;
    }
    
    handle->dataCallback = callback;
}

/**
 * @brief 设置行接收回调函数
 */
void UART_K230_SetLineCallback(UART_K230_Handle_t *handle, UART_K230_LineCallback_t callback)
{
    if (handle == NULL) {
        return;
    }
    
    handle->lineCallback = callback;
}

/**
 * @brief UART_K230中断处理函数
 */
void UART_K230_IRQHandler(UART_K230_Handle_t *handle)
{
    if (handle == NULL) {
        return;
    }

    uint32_t interruptStatus = DL_UART_Main_getPendingInterrupt(handle->instance);
    
    // 处理接收中断
    if (interruptStatus & DL_UART_MAIN_INTERRUPT_RX) {
        while (!DL_UART_Main_isRXFIFOEmpty(handle->instance)) {
            uint8_t data = DL_UART_Main_receiveData(handle->instance);
            
            // 将数据放入接收缓冲区
            UART_K230_RxBufferPut(&handle->rxBuffer, data);
            
            // 如果启用了行模式，处理行缓冲区
            if (handle->lineMode) {
                UART_K230_ProcessLineBuffer(handle, data);
                
                // 如果有完整行且设置了回调函数，调用回调
                if (handle->lineBuffer.ready && handle->lineCallback != NULL) {
                    handle->lineCallback(handle->lineBuffer.buffer);
                    UART_K230_FlushLineBuffer(handle);
                }
            }
            
            // 如果设置了数据回调函数，调用回调
            if (handle->dataCallback != NULL) {
                handle->dataCallback(&data, 1);
            }
            
            handle->lastActivity = UART_K230_GetTick();
        }
    }
    
    // 处理发送中断
    if (interruptStatus & DL_UART_MAIN_INTERRUPT_TX) {
        uint8_t data;
        
        // 从发送缓冲区取数据发送
        while (!DL_UART_Main_isTXFIFOFull(handle->instance) && 
               UART_K230_TxBufferGet(&handle->txBuffer, &data)) {
            DL_UART_Main_transmitData(handle->instance, data);
            handle->lastActivity = UART_K230_GetTick();
        }
        
        // 如果发送缓冲区为空，禁用发送中断
        if (handle->txBuffer.count == 0) {
            DL_UART_Main_disableInterrupt(handle->instance, DL_UART_MAIN_INTERRUPT_TX);
        }
    }
}

/**
 * @brief 设置行模式
 */
void UART_K230_SetLineMode(UART_K230_Handle_t *handle, bool enable)
{
    if (handle == NULL) {
        return;
    }
    
    handle->lineMode = enable;
    
    if (!enable) {
        UART_K230_FlushLineBuffer(handle);
    }
}

/**
 * @brief 获取最后活动时间
 */
uint32_t UART_K230_GetLastActivity(UART_K230_Handle_t *handle)
{
    if (handle == NULL) {
        return 0;
    }
    
    return handle->lastActivity;
}

// 便利函数实现
/**
 * @brief 初始化默认UART_K230
 */
UART_K230_Status_t UART_K230_InitDefault(void)
{
    UART_K230_Config_t config = {
        .baudRate = 115200,
        .enableTxInterrupt = false,  // 发送中断可选择性启用
        .enableRxInterrupt = true,   // 启用接收中断以接收K230数据
        .enableLineMode = true,      // 启用行模式便于处理K230命令
        .lineTerminator = '\n'       // 以换行符为结束符
    };
    
    return UART_K230_Init(&g_defaultK230, &config);
}

/**
 * @brief 使用默认UART_K230发送字符串
 */
UART_K230_Status_t UART_K230_DefaultSendString(const char *str)
{
    return UART_K230_SendString(&g_defaultK230, str);
}

/**
 * @brief 使用默认UART_K230发送一行
 */
UART_K230_Status_t UART_K230_DefaultSendLine(const char *str)
{
    return UART_K230_SendLine(&g_defaultK230, str);
}

/**
 * @brief 使用默认UART_K230格式化输出
 */
UART_K230_Status_t UART_K230_DefaultPrintf(const char *format, ...)
{
    char buffer[512];
    va_list args;
    
    va_start(args, format);
    int len = vsnprintf(buffer, sizeof(buffer), format, args);
    va_end(args);
    
    if (len < 0 || len >= sizeof(buffer)) {
        return UART_K230_STATUS_ERROR;
    }
    
    return UART_K230_SendData(&g_defaultK230, (const uint8_t *)buffer, len);
}

/**
 * @brief 使用默认UART_K230接收一行
 */
UART_K230_Status_t UART_K230_DefaultReceiveLine(char *line, uint16_t maxLength, uint32_t timeout)
{
    return UART_K230_ReceiveLine(&g_defaultK230, line, maxLength, timeout);
}

/**
 * @brief 设置默认UART_K230的数据回调
 */
void UART_K230_DefaultSetDataCallback(UART_K230_DataCallback_t callback)
{
    UART_K230_SetDataCallback(&g_defaultK230, callback);
}

/**
 * @brief 设置默认UART_K230的行回调
 */
void UART_K230_DefaultSetLineCallback(UART_K230_LineCallback_t callback)
{
    UART_K230_SetLineCallback(&g_defaultK230, callback);
}

/**
 * @brief 获取默认UART_K230接收数据数量
 */
uint16_t UART_K230_DefaultGetRxDataCount(void)
{
    return UART_K230_GetRxDataCount(&g_defaultK230);
}

/**
 * @brief 检查默认UART_K230是否有完整行数据
 */
bool UART_K230_DefaultIsLineReady(void)
{
    return UART_K230_IsLineReady(&g_defaultK230);
}

// 私有函数实现
/**
 * @brief 初始化缓冲区
 */
static void UART_K230_BufferInit(UART_K230_TxBuffer_t *txBuf, UART_K230_RxBuffer_t *rxBuf, UART_K230_LineBuffer_t *lineBuf)
{
    if (txBuf != NULL) {
        txBuf->head = 0;
        txBuf->tail = 0;
        txBuf->count = 0;
        memset(txBuf->buffer, 0, sizeof(txBuf->buffer));
    }
    
    if (rxBuf != NULL) {
        rxBuf->head = 0;
        rxBuf->tail = 0;
        rxBuf->count = 0;
        memset(rxBuf->buffer, 0, sizeof(rxBuf->buffer));
    }
    
    if (lineBuf != NULL) {
        lineBuf->length = 0;
        lineBuf->ready = false;
        lineBuf->terminator = '\n';
        memset(lineBuf->buffer, 0, sizeof(lineBuf->buffer));
    }
}

/**
 * @brief 向发送缓冲区放入数据
 */
static bool UART_K230_TxBufferPut(UART_K230_TxBuffer_t *buffer, uint8_t data)
{
    if (buffer == NULL || buffer->count >= UART_K230_TX_BUFFER_SIZE) {
        return false;
    }
    
    buffer->buffer[buffer->head] = data;
    buffer->head = (buffer->head + 1) % UART_K230_TX_BUFFER_SIZE;
    buffer->count++;
    
    return true;
}

/**
 * @brief 从发送缓冲区取出数据
 */
static bool UART_K230_TxBufferGet(UART_K230_TxBuffer_t *buffer, uint8_t *data)
{
    if (buffer == NULL || data == NULL || buffer->count == 0) {
        return false;
    }
    
    *data = buffer->buffer[buffer->tail];
    buffer->tail = (buffer->tail + 1) % UART_K230_TX_BUFFER_SIZE;
    buffer->count--;
    
    return true;
}

/**
 * @brief 向接收缓冲区放入数据
 */
static bool UART_K230_RxBufferPut(UART_K230_RxBuffer_t *buffer, uint8_t data)
{
    if (buffer == NULL || buffer->count >= UART_K230_RX_BUFFER_SIZE) {
        return false;
    }
    
    buffer->buffer[buffer->head] = data;
    buffer->head = (buffer->head + 1) % UART_K230_RX_BUFFER_SIZE;
    buffer->count++;
    
    return true;
}

/**
 * @brief 从接收缓冲区取出数据
 */
static bool UART_K230_RxBufferGet(UART_K230_RxBuffer_t *buffer, uint8_t *data)
{
    if (buffer == NULL || data == NULL || buffer->count == 0) {
        return false;
    }
    
    *data = buffer->buffer[buffer->tail];
    buffer->tail = (buffer->tail + 1) % UART_K230_RX_BUFFER_SIZE;
    buffer->count--;
    
    return true;
}

/**
 * @brief 获取发送缓冲区空闲空间
 */
static uint16_t UART_K230_TxBufferFreeSpace(const UART_K230_TxBuffer_t *buffer)
{
    if (buffer == NULL) {
        return 0;
    }
    
    return UART_K230_TX_BUFFER_SIZE - buffer->count;
}

/**
 * @brief 获取接收缓冲区数据数量
 */
static uint16_t UART_K230_RxBufferDataCount(const UART_K230_RxBuffer_t *buffer)
{
    if (buffer == NULL) {
        return 0;
    }
    
    return buffer->count;
}

/**
 * @brief 启用/禁用中断
 */
static void UART_K230_EnableInterrupts(UART_K230_Handle_t *handle, bool txEnable, bool rxEnable)
{
    if (handle == NULL) {
        return;
    }
    
    if (rxEnable) {
        DL_UART_Main_enableInterrupt(handle->instance, DL_UART_MAIN_INTERRUPT_RX);
    } else {
        DL_UART_Main_disableInterrupt(handle->instance, DL_UART_MAIN_INTERRUPT_RX);
    }
    
    if (txEnable) {
        DL_UART_Main_enableInterrupt(handle->instance, DL_UART_MAIN_INTERRUPT_TX);
    } else {
        DL_UART_Main_disableInterrupt(handle->instance, DL_UART_MAIN_INTERRUPT_TX);
    }
}

/**
 * @brief 获取系统时钟
 */
static uint32_t UART_K230_GetTick(void)
{
    // 使用系统时钟函数
    unsigned long current_time = 0;
    mspm0_get_clock_ms(&current_time);
    return (uint32_t)current_time;
}

/**
 * @brief 检查是否超时
 */
static bool UART_K230_IsTimeout(uint32_t startTime, uint32_t timeout)
{
    if (timeout == 0) {
        return false;  // 无超时
    }
    
    uint32_t currentTime = UART_K230_GetTick();
    return (currentTime - startTime) >= timeout;
}

/**
 * @brief 处理行缓冲区
 */
static void UART_K230_ProcessLineBuffer(UART_K230_Handle_t *handle, uint8_t data)
{
    if (handle == NULL || handle->lineBuffer.ready) {
        return;  // 行缓冲区已满或句柄无效
    }
    
    // 检查是否为行结束符
    if (data == handle->lineBuffer.terminator || data == '\r') {
        handle->lineBuffer.buffer[handle->lineBuffer.length] = '\0';
        handle->lineBuffer.ready = true;
        return;
    }
    
    // 检查是否还有空间
    if (handle->lineBuffer.length >= UART_K230_LINE_BUFFER_SIZE - 1) {
        // 缓冲区满，强制结束当前行
        handle->lineBuffer.buffer[handle->lineBuffer.length] = '\0';
        handle->lineBuffer.ready = true;
        return;
    }
    
    // 添加字符到行缓冲区
    handle->lineBuffer.buffer[handle->lineBuffer.length] = (char)data;
    handle->lineBuffer.length++;
} 